﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using JelloPhysics;
using Microsoft.Xna.Framework;

namespace Cjc.JelloPhone
{
	public partial class MainPage : PhoneApplicationPage
	{
		private World world = new World();
		private Random rand = new Random();
		private Brush borderBrush = new SolidColorBrush( Colors.Black );
		private List<Body> staticBodies = new List<Body>();

		public MainPage()
		{
			InitializeComponent();

			CompositionTarget.Rendering += CompositionTarget_Rendering;
		}

        void MainPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
        {
			CreatePlatforms();
        }

		void CompositionTarget_Rendering( object sender, EventArgs e )
		{
			if ( viewGrid != null )
			{
				var width = viewGrid.ActualWidth;
				var height = viewGrid.ActualHeight;

				if ( width > 0 && height > 0 )
				{
					if ( staticBodies.Count < 1 ) CreatePlatforms();

					for ( int i = 0; i < 6; i++ ) world.update( 1 / 120f );

					var removed = new List<Body>();

					foreach ( var body in world )
					{
						var shape = body.ObjectTag as Polygon;

						if ( shape == null )
						{
							shape = new Polygon();
							shape.Fill = new SolidColorBrush( Color.FromArgb( 255, (byte)rand.Next( 255 ), (byte)rand.Next( 255 ), (byte)rand.Next( 255 ) ) );
							shape.StrokeThickness = 4;
							shape.Stroke = borderBrush;
							viewGrid.Children.Add( shape );
							body.ObjectTag = shape;
						}

						var points = new PointCollection();
						var visible = false;
						var scale = height / 50;

						foreach ( var pm in body )
						{
							var x = ( width / 2 ) + ( pm.Position.X * scale );
							var y = ( height / 2 ) - ( pm.Position.Y * scale );

							if ( x >= 0 && x < width && y >= 0 && y < height ) visible = true;

							points.Add( new Point( x, y ) );
						}

						shape.Points = points;

						if ( !visible ) removed.Add( body );
					}

					foreach ( var body in removed )
					{
						world.removeBody( body );
						viewGrid.Children.Remove( body.ObjectTag as Shape );
					}
				}
			}
		}

		private void CreatePlatforms()
		{
			foreach ( var body in staticBodies )
			{
				world.removeBody( body );
                viewGrid.Children.Remove(body.ObjectTag as Shape);
			}

            var scale = viewGrid.ActualHeight / 10;
			var halfScale = scale / 2;

			for ( int index = 0; index < 10; ++index )
			{
				var width = (float)( 3f + ( rand.NextDouble() * 10 ) );

				// static ground object.
				var groundShape = new ClosedShape();
				groundShape.begin();
				groundShape.addVertex( new Vector2( -width, -1f ) );
				groundShape.addVertex( new Vector2( -width, 1f ) );
				groundShape.addVertex( new Vector2( width, 1f ) );
				groundShape.addVertex( new Vector2( width, -1f ) );
				groundShape.finish();

				// make the body.
				var groundBody = new Body(
					world,
					groundShape,
					float.PositiveInfinity,
					new Vector2( (float)( ( rand.NextDouble() * scale ) - halfScale ), (float)( ( rand.NextDouble() * scale * 0.75 ) - halfScale - 5 ) ),
					(float)( ( rand.NextDouble() * Math.PI / 8 ) - ( Math.PI / 16 ) ),
					Vector2.One,
					false );

				staticBodies.Add( groundBody );
			}
		}

		private void DropBalloon( object sender, RoutedEventArgs e )
		{
			var shape = new ClosedShape();
			shape.begin();

			for ( var rad = 0d; rad < Math.PI * 2; rad += Math.PI / 10 )
			{
				shape.addVertex( new Vector2( (float)Math.Sin( rad ), (float)Math.Cos( rad ) /** 0.75f*/ ) );
			}

			/*			shape.addVertex( new Vector2( -1.0f, 0f ) );
						shape.addVertex( new Vector2( 0f, 1.0f ) );
						shape.addVertex( new Vector2( 1.0f, 0f ) );
						shape.addVertex( new Vector2( 0f, -1.0f ) );*/
			shape.finish();

            var scale = viewGrid.ActualHeight / 50;
			var itemScale = (float)( 1f + ( 2f * rand.NextDouble() ) );
			/*
						var body = new FallingBody( world, shape, 1f, 40f, 1500f, 20f, 1500f, 20f,
							new Vector2( 0, 20 ), MathHelper.ToRadians( new Random().Next( 360 ) ), new Vector2( itemScale ) );
			*/
			var body = new FallingBody( world, shape, 1f, 40f, 100f, 10f, 100f, 10f,
				new Vector2( (float)( ( rand.NextDouble() * scale ) - ( scale / 2 ) ), 20 ),
				MathHelper.ToRadians( new Random().Next( 360 ) ),
				new Vector2( itemScale ) );

			var count = shape.Vertices.Count;

			for ( int index = 0; index < count; ++index )
			{
				body.addInternalSpring( index, ( index + 4 ) % count, 400f, 12f );
			}

			//			body.addInternalSpring( 1, 3, 400f, 12f );
		}

		private void MovePlatforms( object sender, RoutedEventArgs e )
		{
			CreatePlatforms();
		}
	}
}